package com.haoyeteng.sxbd.modular.business.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.haoyeteng.sxbd.core.constant.DeleteFlag;
import com.haoyeteng.sxbd.core.constant.SxbdConstants;
import com.haoyeteng.sxbd.core.exception.SxbdException;
import com.haoyeteng.sxbd.core.util.DateUtil;
import com.haoyeteng.sxbd.core.util.MD5Util;
import com.haoyeteng.sxbd.core.util.NumUtil;
import com.haoyeteng.sxbd.core.util.ToolUtil;
import com.haoyeteng.sxbd.modular.business.dao.OrderMapper;
import com.haoyeteng.sxbd.modular.business.model.*;
import com.haoyeteng.sxbd.modular.business.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author haoyeteng123
 * @since 2019-05-28
 */
@Service
@Transactional
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

	@Autowired
	private IOrderDtlService orderDtlService;

	@Autowired
	private IProductService productService;

	@Autowired
	private IAccountService accountService;

	@Autowired
	private IOrderDtlAccountService orderDtlAccountService;

	@Autowired
	private IShopCartService shopCartService;

	@Autowired
	private IEleFenceService eleFenceService;

	@Autowired
	private IServiceBuyingService serviceBuyingService;

	/**
	 * 订单分页查询
	 * @param page 分页
	 * @param params 参数
	 * @return List<map>
	 */
	@Override
	public List<Map<String, Object>> selectOrders(Page<Order> page, Map<String,Object> params){
		return this.baseMapper.selectOrders(page, params);
	}
	/**
	 * 订单查询
	 * @param params 参数
	 * @return List<map>
	 */
	@Override
	public List<Map<String, Object>> selectOrdersList(Map<String,Object> params){
		return this.baseMapper.selectOrdersList(params);
	}

	/**
	 * 1.插入订单及明细 2.删除购物车 3.若orderDtlId明细不为空 取出暂存在orderDtlId的accountId 插入订单明细账号表
	 * @param order 订单（含明细）
	 * @return order
	 */
	@Override
	public Order insertAndDtl(Order order){
		Date date = new Date();
		order.setCreateTime(date);
		order.setUpdateTime(date);
		order.setOrderId("O-"+DateUtil.getAllTime() + ToolUtil.getRandomString(8));
		order.setPayState(SxbdConstants.ORDER_PAY_STATE_NOPAY);
		order.setOrderState(SxbdConstants.ORDER_STATE_NEW);
		//插入随机的汇款平证号 不需要插入
		//order.setSwiftNo(ToolUtil.getRandomString(8));
		order.setFlag(DeleteFlag.OK.getCode());

		//插入订单
		this.baseMapper.insert(order);

		List<OrderDtl> details = order.getDetails();
		if (ToolUtil.isNotEmpty(details)) {
			//插入明细
			details.forEach(subDtl -> {
				//orderDtlId明细为空
				Integer orderDtlId = subDtl.getOrderDtlId();

				subDtl.setOrderDtlId(null);
				subDtl.setCreateTime(date);
				subDtl.setOrderId(order.getOrderId());
				subDtl.setFlag(DeleteFlag.OK.getCode());
				orderDtlService.insert(subDtl);

				//2.删除购物车物品
				Integer shopCartId = subDtl.getShopCartId();
				if (ToolUtil.isNotEmpty(shopCartId)){
					shopCartService.deleteById(shopCartId);
				}

				//3.若orderDtlId明细不为空 取出暂存在orderDtlId的accountId 插入订单明细账号表
				if (ToolUtil.isNotEmpty(orderDtlId)) {
					OrderDtlAccount orderDtlAccount = new OrderDtlAccount();
					orderDtlAccount.setAccountId(orderDtlId);
					orderDtlAccount.setOrderDtlId(subDtl.getOrderDtlId());
					orderDtlAccount.setCreateTime(date);
					orderDtlAccount.setRemark("服务续费");
					orderDtlAccountService.insert(orderDtlAccount);
				}

			});
		}else{
			throw new SxbdException(-1, "未获取到订单明细！");
		}
		return order;
	}

	/**
	 * 修改订单表
	 * 1.修改支付状态为已支付
	 * 2.生成差分账号 ; 若续费更新账号
	 * @param order 订单
	 */
	@Override
	public boolean updateAndSaveAccount(Order order){
		boolean flag = false;
		EleFence eleFence = eleFenceService.selectOne(new EntityWrapper<EleFence>().orderBy("ele_fence_id").last("limit 1"));

		//1.修改支付状态为已支付
		Date date = new Date();
		Order orderVo = new Order();
		orderVo.setOrderId(order.getOrderId());
		//设置支付方式
		if (ToolUtil.isNotEmpty(order.getPayType())){
			orderVo.setPayType(order.getPayType());
		}
		//设置支付状态 已支付
		orderVo.setPayState(SxbdConstants.ORDER_PAY_STATE_PAYMENTED);
		orderVo.setUpdateTime(date);
		orderVo.setPayTime(date);
		Integer orderResult = this.baseMapper.updateById(orderVo);
		if(orderResult == 1) {
			flag = true;
		}

		//2.根据订单明细生成差分账号; 若续费更新账号
		for (OrderDtl orderDtl : order.getDetails()) {
			Product product = productService.selectById(orderDtl.getProductId());
			if (ToolUtil.isEmpty(product)) {
				throw new SxbdException("商品Id：" + orderDtl.getProductId() + "不存在该商品！");
			}
			//账号服务类型
            String serviceType = product.getServiceType();
            //下单人
			Integer userId = order.getUserId();

			//RTK RTD 差分账号 可能续费
			if (SxbdConstants.SERVICE_TYPE_RTD.toUpperCase().equals(serviceType)
					|| SxbdConstants.SERVICE_TYPE_RTK.toUpperCase().equals(serviceType)) {
				//校验关联
				OrderDtlAccount dtlAccount = orderDtlAccountService.selectOne(new EntityWrapper<OrderDtlAccount>()
						.eq("order_dtl_id", orderDtl.getOrderDtlId()));
				//存在关联账号 即服务续费
				if (ToolUtil.isNotEmpty(dtlAccount) && ToolUtil.isNotEmpty(dtlAccount.getAccountId())) {
					Account account = accountService.selectById(dtlAccount.getAccountId());
					if (ToolUtil.isEmpty(account)) {
						throw new SxbdException("订单明细Id：" + orderDtl.getOrderDtlId() + "续费账号不存在！");
					}
					if (ToolUtil.isEmpty(account.getPayTime())||ToolUtil.isEmpty(account.getStartTime())) {
						throw new SxbdException("订单明细Id：" + orderDtl.getOrderDtlId() + " 续费账号："+account.getAccount()+"使用记录错误,无法续费！");
					}
					//账号时长 (单位月)
					Integer accountPayTime;
					if(SxbdConstants.ORDERDTL_CHARGE_TYPE_YEAR.equals(orderDtl.getChargeType())){
						accountPayTime = orderDtl.getPayTime() * 12;
					} else if (SxbdConstants.ORDERDTL_CHARGE_TYPE_MONTH.equals(orderDtl.getChargeType())) {
						accountPayTime = orderDtl.getPayTime();
					} else {
						throw new SxbdException("没有选择对应的计费类型！");
					}
					//剩余天数
					Long overTime = this.getOverTime(account.getPayTime(), account.getStartTime());
					Account accountVo = new Account();
					accountVo.setAccountId(account.getAccountId());
					accountVo.setUpdateTime(date);
					//未到期 直接加账号时长
					if (overTime >= 0){
						accountVo.setPayTime(account.getPayTime() + accountPayTime);
					}else {
					//已到期 更新开始时间 和时长
						accountVo.setStartTime(date);
						accountVo.setPayTime(accountPayTime);
					}
					accountService.updateById(accountVo);
				}else{
					//新建账号
					for(int i = 0; i < orderDtl.getTheCount(); i++){
						Account account = new Account();
                        String preAccount = "shy";
                        int count = accountService.selectCount(new EntityWrapper<Account>().eq("user_id", userId).like("account", preAccount));
						String userIdFormat = NumUtil.autoGenericCode(userId, 4);
						String accountFormat = NumUtil.autoGenericCode(count + 1, 4);
						String accountStr = preAccount+userIdFormat+accountFormat;
						//判断是否会出现重复账号
						int count1 = 0;
						do{
							if (count1 > 0) {
								count++;
								accountStr = preAccount + userIdFormat + NumUtil.autoGenericCode(count + 1, 4);
							}
							count1 = accountService.selectCount(new EntityWrapper<Account>().eq("account", accountStr));
						}while (count1 != 0);

						account.setAccount(accountStr);
						account.setPassword(MD5Util.DEFULT_PASSWORD);
						account.setUserId(userId);
						account.setServiceType(serviceType);
						//账号时长 (单位月)
						Integer accountPayTime;
						if(SxbdConstants.ORDERDTL_CHARGE_TYPE_YEAR.equals(orderDtl.getChargeType())){
							accountPayTime = orderDtl.getPayTime() * 12;
						} else if (SxbdConstants.ORDERDTL_CHARGE_TYPE_MONTH.equals(orderDtl.getChargeType())) {
							accountPayTime = orderDtl.getPayTime();
						} else {
							throw new SxbdException("没有选择对应的计费类型！");
						}
						account.setPayTime(accountPayTime);
						account.setBindingState(SxbdConstants.ACCOUNT_BINDING_STATE_NO);
						account.setCreateTime(date);
						account.setUpdateTime(date);
						account.setFlag(DeleteFlag.OK.getCode());
						account.setEleFenceId(ToolUtil.isNotEmpty(eleFence) ? eleFence.getEleFenceId() : null);
						accountService.insert(account);

						OrderDtlAccount orderDtlAccount = new OrderDtlAccount();
						orderDtlAccount.setOrderDtlId(orderDtl.getOrderDtlId());
						orderDtlAccount.setAccountId(account.getAccountId());
						orderDtlAccount.setCreateTime(date);
						orderDtlAccountService.insert(orderDtlAccount);
					}
				}
			} else if (SxbdConstants.SERVICE_TYPE_JZSJ.toUpperCase().equals(serviceType) || SxbdConstants.SERVICE_TYPE_ZBZH.toUpperCase().equals(serviceType)) {
				//基站数据 坐标转换
                this.saveAccount(orderDtl, serviceType, userId);
			}

		}
		
		return flag;
	}

    /**
     * jzsj zbzh插入账号和关联表
     * @param orderDtl 订单明细
     * @param serviceType 服务类型(大写)
     * @param userId 用户
     */
    public void saveAccount(OrderDtl orderDtl, String serviceType, Integer userId) {
        Date date = new Date();
        Account account = new Account();
        Integer count = accountService.selectCount(new EntityWrapper<Account>().eq("user_id", userId).eq("service_type", serviceType));
        //账号前缀
        String preAccount = serviceType.toLowerCase();
        String userIdFormat = NumUtil.autoGenericCode(userId, 4);
        String accountFormat = NumUtil.autoGenericCode(count + 1, 4);
        account.setAccount(preAccount+userIdFormat+accountFormat);

        account.setUserId(userId);
        account.setServiceType(serviceType);
        account.setTaskName(orderDtl.getTaskName());
        //账号时长 1s 单位小时 15s 30s 单位天
        account.setPayTime(orderDtl.getPayTime());
        if (SxbdConstants.SERVICE_TYPE_JZSJ.toUpperCase().equals(serviceType)) {
            account.setStartTime(orderDtl.getStartTime());
            account.setEndTime(orderDtl.getEndTime());
            account.setFileCount(orderDtl.getTheCount());
            account.setBroadcastFrequency(orderDtl.getBroadcastFrequency());
        }
        if (SxbdConstants.SERVICE_TYPE_ZBZH.toUpperCase().equals(serviceType)) {
            account.setTransformMode(orderDtl.getTransformMode());
            account.setFileIds(orderDtl.getFileIds());
			account.setFileCount(orderDtl.getFileCount());
        }
        account.setCreateTime(date);
        account.setUpdateTime(date);
        account.setFlag(DeleteFlag.OK.getCode());
        accountService.insert(account);

        //插入关联表
        OrderDtlAccount orderDtlAccount = new OrderDtlAccount();
        orderDtlAccount.setOrderDtlId(orderDtl.getOrderDtlId());
        orderDtlAccount.setAccountId(account.getAccountId());
        orderDtlAccount.setCreateTime(date);
        orderDtlAccountService.insert(orderDtlAccount);
    }

    /**
	 * 剩余天数
	 * @param payTime 购买时长
	 * @param startTime 开始时间
	 * @return 天数
	 */
	private Long getOverTime(Integer payTime, Date startTime) {
		String startTimeTemp = DateUtil.format(startTime, "yyyy-MM-dd HH:mm:ss");
		//服务到期日期
		String endTime = DateUtil.addMonth(startTimeTemp, "yyyy-MM-dd HH:mm:ss", payTime);
		//服务总天数
		Long totleDays = DateUtil.getDaySub(startTimeTemp, endTime);
		//已经使用服务的天数
		Long useDays = DateUtil.getDaySub(startTimeTemp, DateUtil.getTime());
		//剩余天数
		return totleDays - useDays;
	}

	/**
	 * 查询订单(含明细)
	 * @param orderId 订单Id
	 * @return 订单(含明细)
	 */
	@Override
	public Order selectOrderAndDtlById(String orderId){
		Order order = this.baseMapper.selectById(orderId);
		if (ToolUtil.isNotEmpty(order)) {
			List<OrderDtl> orderDtls = orderDtlService.selectList(new EntityWrapper<OrderDtl>().eq("order_id", orderId));
			order.setDetails(orderDtls);
		}
		return order;
	}

	/**
	 *删除订单及明细
	 */
	@Override
	public void deleteOrderAndDtlById(String orderId){
		Order order = this.selectOrderAndDtlById(orderId);
		this.baseMapper.deleteById(orderId);
		for (OrderDtl dtl : order.getDetails()) {
			orderDtlService.deleteById(dtl.getOrderDtlId());
		}
	}

	/**
	 * 插入免费订单 支付成功 总额0
	 * @param order 订单（含明细）
	 * @return order
	 */
	@Override
	public Order addFreeSuccess(Order order){

		//1.新增订单及明细 2.删除购物车
		Order orderVo = this.insertAndDtl(order);

		if (ToolUtil.isEmpty(orderVo)) {
			throw new SxbdException("未获取到订单信息！");
		}
		if (ToolUtil.isEmpty(orderVo.getOrderId())){
			throw new SxbdException("未获取到订单信息！");
		}

		//校验
		Order orderAndDtl = this.selectOrderAndDtlById(order.getOrderId());
		if (ToolUtil.isEmpty(orderAndDtl)){
			throw new SxbdException("订单不存在！");
		}
		if (!SxbdConstants.ORDER_PAY_STATE_NOPAY.equals(orderAndDtl.getPayState())){
			throw new SxbdException("订单Id:" + order.getOrderId() + "不是待支付状态!");
		}
		if (ToolUtil.isEmpty(orderAndDtl.getDetails())){
			throw new SxbdException("获取订单Id:" + order.getOrderId() + "明细信息失败!");
		}

		/**确认支付
		 * 修改订单表
		 * 1.修改支付状态为已支付
		 * 2.生成差分账号
		 * @param order 订单
		 */
		this.updateAndSaveAccount(orderAndDtl);
		return orderAndDtl;
	}

	@Override
	public List<Map<String, Object>> selectOrderForCurveByDay() {
		return this.baseMapper.selectOrderForCurveByDay();
	}
	@Override
	public List<Map<String, Object>> selectOrderForCurveByMonth() {
		return this.baseMapper.selectOrderForCurveByMonth();
	}
	@Override
	public List<Map<String, Object>> selectOrderForCurveByYear() {
		return this.baseMapper.selectOrderForCurveByYear();
	}

}
